from fastapi import FastAPI, Request, WebSocket, File, UploadFile, Body
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse,JSONResponse
from fastapi.middleware.cors import CORSMiddleware 
import uvicorn
from biz.integrations.asr.handle_websocket import handle_websocket, get_active_assistants
from biz.config.settings import ASRConfig
import base64
from typing import Dict
from biz.utils.logger import logger
from biz.integrations.aliyun.speech_recognition_api import recognize_audio

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
async def get(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await handle_websocket(websocket)

@app.post("/api/speech-recognition/blob")
async def speech_recognition_blob(audio_file: UploadFile = File(...)):
    try:
        # 读取上传的音频文件内容
        audio_content = await audio_file.read()

        text = recognize_audio(bytes(audio_content), num_processes=1, timeout=30)
        logger.info(f"FunASR识别结果: {text}")
        
        # 临时返回结果，实际应替换为真实的语音识别结果
        result = {"text": text}
        return JSONResponse(content={"success": True, "result": result})
    except Exception as e:
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})

@app.post("/api/speech-recognition/base64")
async def speech_recognition_base64(data: Dict[str, str] = Body(...)):
    try:
        # 从请求体中获取base64编码的音频数据
        base64_audio = data.get("audio")
        if not base64_audio:
            return JSONResponse(status_code=400, content={"success": False, "error": "未提供音频数据"})
        
        # 解码base64数据
        audio_content = base64.b64decode(base64_audio)
        logger.info(f"接收到的base64音频流: {audio_content}")
        text = recognize_audio(bytes(audio_content), num_processes=1, timeout=30)
        logger.info(f"FunASR识别结果: {text}")
        result = {"text": text}
        return JSONResponse(content={"success": True, "result": result})
    except Exception as e:
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})

@app.post("/api/voice-assistant/wake-control")
async def voice_assistant_wake_control(data: Dict = Body(...)):
    try:
        client_id = data.get("client_id")
        is_waked = data.get("is_waked")
        wake_word_detected = data.get("wake_word_detected")
        
        if client_id is None:
            return JSONResponse(status_code=400, content={"success": False, "error": "未提供client_id参数"})
        
        # 将client_id转换为整数
        try:
            client_id = int(client_id)
        except ValueError:
            return JSONResponse(status_code=400, content={"success": False, "error": "client_id必须是一个有效的整数"})
        
        active_assistants = get_active_assistants()
        if not active_assistants:
            return JSONResponse(status_code=404, content={"success": False, "error": "没有活跃的语音助手"})
        
        if client_id not in active_assistants:
            return JSONResponse(status_code=404, content={"success": False, "error": f"找不到ID为{client_id}的语音助手实例"})
        
        # 更新指定的语音助手实例状态
        assistant = active_assistants[client_id]
        if is_waked is not None:
            assistant.is_waked = is_waked
        if wake_word_detected is not None:
            assistant.wake_word_detected = wake_word_detected
        
        return JSONResponse(content={
            "success": True, 
            "message": f"已更新ID为{client_id}的语音助手状态"
        })
    except Exception as e:
        logger.error(f"控制唤醒状态时发生错误: {str(e)}")
        return JSONResponse(status_code=500, content={"success": False, "error": str(e)})


if __name__ == "__main__":
    uvicorn.run(app, host=ASRConfig.HOST, port=ASRConfig.PORT)